package com.fudan.backend.service.impl;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.TypeReference;
import com.fudan.backend.exception.BaseException;
import com.fudan.backend.exception.RetCode;
import com.fudan.backend.service.ImgService;
import com.qiniu.common.QiniuException;
import com.qiniu.http.Response;
import com.qiniu.storage.Configuration;
import com.qiniu.storage.Region;
import com.qiniu.storage.UploadManager;
import com.qiniu.storage.model.DefaultPutRet;
import com.qiniu.util.Auth;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.system.ApplicationHome;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.InputStream;
import java.nio.file.Files;
import java.util.*;

@Service
@Data
@ConfigurationProperties(prefix = "qiniu-oss")
public class ImgServiceImpl implements ImgService {
    private String accessKey;
    private String secretKey;
    private String bucket;
    private String testUrl;
    private String domain;
    private static Set<String> imgFileType = new HashSet<>();
    static {
        imgFileType.add(".jpg");
        imgFileType.add(".jpeg");
        imgFileType.add(".png");
        imgFileType.add(".svg");
        imgFileType.add(".gif");
        imgFileType.add(".bmp");
        imgFileType.add(".webp");
    }
    @Override
    public List<String> uploadRemote(MultipartFile[] files) {
        List<String> urlList = new ArrayList<>();
        //验证文件类型
        this.checkFileType(files);
        for(MultipartFile file : files){
            String fileName = this.genFileName(file);
            //构造一个带指定 Region 对象的配置类
            Configuration cfg = new Configuration(Region.autoRegion());
            UploadManager uploadManager = new UploadManager(cfg);
            //默认不指定key的情况下，以文件内容的hash值作为文件名
            String key = fileName;
            try {
                InputStream inputStream = file.getInputStream();
                Auth auth = Auth.create(accessKey, secretKey);
                String upToken = auth.uploadToken(bucket);
                try {
                    Response response = uploadManager.put(inputStream, key, upToken, null, null);
                    //解析上传成功的结果
                    DefaultPutRet putRet = JSON.parseObject(response.bodyString(), new TypeReference<DefaultPutRet>() {
                    });
                    System.out.println(putRet.key);
                    System.out.println(putRet.hash);
                    //返回文件的url
                    urlList.add(key);
                } catch (QiniuException ex) {
                    Response r = ex.response;
                    System.err.println(r.toString());
                    throw new BaseException(RetCode.IMG_UPLOAD_FAIL);
                }
            }
            catch (Exception e) {
                throw new BaseException(RetCode.IMG_UPLOAD_FAIL);
            }
        }
        return urlList;
    }

    @Override
    public List<String> saveLocal(MultipartFile[] files) {
        List<String> fileUrlList = new ArrayList<>();
        //验证files文件类型
        this.checkFileType(files);
        ApplicationHome applicationHome = new ApplicationHome(this.getClass());
        String imagePath = applicationHome.getDir().getParentFile().getParentFile().getAbsolutePath()
                + "\\src\\main\\resources\\images\\";
        String imagePathTar = applicationHome.getDir().getAbsolutePath() + "\\images\\";

        for (MultipartFile multiFile : files) {
           String fileName = this.genFileName(multiFile);
            //创建imagePath所对应的File对象
            File file = new File(imagePath);
            File fileTar = new File(imagePathTar);
            //判断file所对应目录是否存在
            if (!file.exists()){
                try{
                    file.mkdir();
                }
                catch(Exception e){
                    throw new BaseException(RetCode.IMG_UPLOAD_FAIL);
                }
            }
            if (!fileTar.exists())
                try{
                    fileTar.mkdir();
                }
                catch(Exception e){
                    throw new BaseException(RetCode.IMG_UPLOAD_FAIL);
                }
            // 构造实际路径
            String finalPath = imagePath + File.separator + fileName;
            String finalPathTar = imagePathTar + File.separator + fileName;
            // 写入文件
            try{
                File finalFile = new File(finalPath);
                multiFile.transferTo(finalFile);
                File finalFileTar = new File(finalPathTar);
                Files.copy(finalFile.toPath(), finalFileTar.toPath());
            }
            catch (Exception e){
                throw new BaseException(RetCode.IMG_UPLOAD_FAIL);
            }
            // 保存fileUrl到fileUrlList中
            fileUrlList.add(fileName);
        }
        return fileUrlList;
    }
    private void checkFileType(MultipartFile[] files){
        if(files == null){
            throw new BaseException(RetCode.EMPTY_FILE);
        }
        for(MultipartFile file : files){
            String fileName = file.getOriginalFilename();
            //文件名不为空
            if(fileName == null){
                throw new BaseException(RetCode.IMG_NAME_NULL);
            }
            //文件类型符合要求
            String suffixName = fileName.substring(fileName.lastIndexOf('.'));
            if(!imgFileType.contains(suffixName)){
                throw new BaseException(RetCode.FILE_TYPE_ERROR);
            }
        }
    }

    private String genFileName(MultipartFile file){
        String fileName = file.getOriginalFilename();
        // 获取上传的文件的后缀名
        String suffixName = fileName.substring(fileName.lastIndexOf('.'));
        // 获取uuid
        String uuid = UUID.randomUUID().toString();
        // 拼接一个新的文件名
        return uuid + suffixName;
    }
}
